#include <Wire.h>

//TruckPC - Peumans Joris - 2008 - v1
//read master-command from serial port, command starts with "$" and ends withs "#" or "0" if counter needs to be set zero
//sends back information, always ends with "!"
//A=analogue port
//D=digital port
//C=counter, counter will be set to zero when send to master
//IT=I2C Temperature (LM75) sensor

volatile char Counter;
volatile int SerialValue;
volatile int Command;
volatile int CommandPost;
volatile int Port;

// analogue
volatile long A0=0;
volatile long A1=0;
volatile long A2=0;
volatile long A3=0;
volatile long A4=0;
volatile long A5=0;
volatile long A6=0;
volatile long A7=0;

//digital
volatile long D4=0;
volatile long D5=0;
volatile long D6=0;
volatile long D7=0;
volatile long D8=0;
volatile long D9=0;

//counters
volatile long C1=0;
volatile long C2=0;

int val=0;

#define CommandBegin 36 //$
#define CommandEnd 35 // #
#define FeedbackEnd 33 //!
#define AnalogType 65 // A
#define DigitalType 68 // D
#define CounterType 67 // C
#define I2CType 73 // I
#define Zero 48 //0
#define One 49 //1
#define Two 50
#define Three 51
#define Four 52
#define Five 53
#define Six 54
#define Seven 55
#define Eight 56
#define Nine 57 //9
#define Temperature 84 // T

 void setup()
 {
   Counter = '1';
   Wire.begin();
   attachInterrupt(0, Count, FALLING); // when hall sensor goes from high to low, call function to add extra tick
   Serial.begin(19200);                     // open serial port
   digitalWrite(4, LOW);
   digitalWrite(5, LOW);
   digitalWrite(6, LOW);
   digitalWrite(7, LOW);
   digitalWrite(8, LOW);
   digitalWrite(9, LOW);
   pinMode(4, INPUT);
   pinMode(5, INPUT);
   pinMode(6, INPUT);
   pinMode(7, INPUT);
   pinMode(8, INPUT);
   pinMode(9, INPUT);
 
 }

 void loop()
 {
  // read command
  do {
     SerialValue = Serial.read(); }
  while (SerialValue == -1);
  if (SerialValue == CommandBegin)
     {
      do {
         SerialValue = Serial.read(); }
      while (SerialValue == -1);
      Command = SerialValue;
      do {
         SerialValue = Serial.read(); }
      while (SerialValue == -1);
      Port = SerialValue;
      do {
         SerialValue = Serial.read(); }
      while (SerialValue == -1);
      CommandPost = SerialValue;
      GiveValue(Command, Port, CommandPost);
     }
 }

 void Count()
 {
   if (Counter == '1')
      {
       C1++;
      }
   else
      {
       C2++;
      }
 }

 void GiveValue(int Command, int Port, int CommandPost)
 {
   if (Command == AnalogType)
       {
         switch (Port) {
           case Zero:
             Serial.print("$A0#");
             Serial.print(GiveSensor("A0"));
             Serial.println("!");
             return;
           case One:
             Serial.print("$A1#");
             Serial.print(GiveSensor("A1"));
             Serial.println("!");
             return;
           case Two:
             Serial.print("$A2#");
             Serial.print(GiveSensor("A2"));
             Serial.println("!");
             return;
           case Three:
             Serial.print("$A3#");
             Serial.print(GiveSensor("A3"));
             Serial.println("!");
             return;
           case Four:
             Serial.print("$A4#");
             Serial.print(GiveSensor("A4"));
             Serial.println("!");
             return;
           case Five:
             Serial.print("$A5#");
             Serial.print(GiveSensor("A5"));
             Serial.println("!");
             return;
           case Six:
             Serial.print("$A6#");
             Serial.print(GiveSensor("A6"));
             Serial.println("!");
             return;
           case Seven:
             Serial.print("$A7#");
             Serial.print(GiveSensor("A7"));
             Serial.println("!");
             return;
           default:
             Serial.println("$ERROR!");
             return;
          }
         } 
   if (Command == DigitalType)
       {
         switch (Port) {
           case Four:
             Serial.print("$D4#");
             Serial.print(GiveSensor("D4"));
             Serial.println("!");
             return;
           case Five:
             Serial.print("$D5#");
             Serial.print(GiveSensor("D5"));
             Serial.println("!");
             return;
           case Six:
             Serial.print("$D6#");
             Serial.print(GiveSensor("D6"));
             Serial.println("!");
             return;
           case Seven:
             Serial.print("$D7#");
             Serial.print(GiveSensor("D7"));
             Serial.println("!");
             return;
           case Eight:
             Serial.print("$D8#");
             Serial.print(GiveSensor("D8"));
             Serial.println("!");
             return;
           case Nine:
             Serial.print("$D9#");
             Serial.print(GiveSensor("D9"));
             Serial.println("!");
             return;
           default:
             Serial.println("$ERROR!");
             return;
          }
         } 
   if (Command == CounterType)
       {
           if (Counter == '1')
              {
              Counter = '2';
              Serial.print("$C#");
              Serial.print(C1);
              Serial.println("!");
              C1 = 0;
              return;
              }
           else
              {
              Counter = '1';
              Serial.print("$C#");
              Serial.print(C2);
              Serial.println("!");
              C2 = 0;
              return;
              }
         } 
   if (Command == I2CType)
       {
         switch (Port) {
           case Temperature:
             Serial.print("$IT#");
             //start routine for reading temperature I2C LM75 sensors
             Serial.print(LM75());
             Serial.println("!");
             return;
           default:
             Serial.println("$ERROR!");
             return;
          }
         } 
   Serial.println("$ERROR!");
         
 }
 int GiveSensor(char* Sensor)
 {
   if (Sensor == "A0")
      {return analogRead(0);}
   if (Sensor == "A1")
      {return analogRead(1);}
   if (Sensor == "A2")
      {return analogRead(2);}
   if (Sensor == "A3")
      {return analogRead(3);}
   if (Sensor == "A4")
      {return analogRead(4);}
   if (Sensor == "A5")
      {return analogRead(5);}
   if (Sensor == "A6")
      {return analogRead(6);}
   if (Sensor == "A7")
      {return analogRead(7);}
   if (Sensor == "D4")
      {return digitalRead(4);}
   if (Sensor == "D5")
      {return digitalRead(5);}
   if (Sensor == "D6")
      {return digitalRead(6);}
   if (Sensor == "D7")
      {return digitalRead(7);}
   if (Sensor == "D8")
      {return digitalRead(8);}
   if (Sensor == "D9")
      {return digitalRead(9);}
   return 0;
 } 
 int LM75()
 {
   byte TemperatureByte;
   byte LowerByte;
   
   Wire.beginTransmission(B1001000); // transmit to device #0 
   Wire.send(0x00);           // sends one byte  
   Wire.endTransmission();    // stop transmitting 
   
   Wire.requestFrom(B1001000, 2);     // request 2 bytes from slave device #0 
   while(Wire.available())      // slave may send less than requested 
        { 
         TemperatureByte = Wire.receive();
         LowerByte = Wire.receive();
        } 
   return TemperatureByte;

 }

